package com.hk.core.web.reactive;

import com.hk.commons.util.StringEscapeHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import reactor.core.publisher.Flux;

import java.net.URI;
import java.util.Map;
import java.util.Objects;

/**
 * @author Kevin
 * @date 2022/11/28 22:53
 */
@RequiredArgsConstructor
public class XssServerHttpRequest implements ServerHttpRequest {

    private final ServerHttpRequest serverHttpRequest;

    private final StringEscapeHandler stringEscapeHandler;

    private MultiValueMap<String, String> queryParams;

    @Override
    public String getId() {
        return serverHttpRequest.getId();
    }

    @Override
    public RequestPath getPath() {
        return serverHttpRequest.getPath();
    }

    @Override
    public MultiValueMap<String, String> getQueryParams() {
        MultiValueMap<String, String> params = serverHttpRequest.getQueryParams();
        if (Objects.isNull(this.queryParams)) {
            var map = new LinkedMultiValueMap<String, String>(params.size());
            params.forEach((key, value) -> map.put(key, value.stream()
                    .map(stringEscapeHandler::escape).toList()));
            this.queryParams = CollectionUtils.unmodifiableMultiValueMap(map);
        }
        return this.queryParams;
    }

    @Override
    public MultiValueMap<String, HttpCookie> getCookies() {
        return serverHttpRequest.getCookies();
    }

    @Override
    public HttpMethod getMethod() {
        return serverHttpRequest.getMethod();
    }

    @Override
    public URI getURI() {
        return serverHttpRequest.getURI();
    }

    @Override
    public Map<String, Object> getAttributes() {
        return serverHttpRequest.getAttributes();
    }

    @Override
    public Flux<DataBuffer> getBody() {
        return serverHttpRequest.getBody();
//                .map(buffer -> {
//                    var bodyString = buffer.toString(StandardCharsets.UTF_8);
//                    return buffer.writePosition(0) //从头开始写
//                            .write(stringEscapeHandler.escape(bodyString), StandardCharsets.UTF_8);
//                });
    }

    @Override
    public HttpHeaders getHeaders() {
        return serverHttpRequest.getHeaders();
    }
}
